﻿using JT808Protocol.Abstracts;
using JT808Protocol.Methods;
using JT808Protocol.Models;
using Microsoft.Extensions.Hosting;
using SuperSocket;
using System;
using System.Collections.Generic;

namespace JT808Gateway.Core
{
    /// <summary>
    /// JT808网关Builder
    /// </summary>
    public class JT808GatewayHostBuilder
    {
        private IHost _jT808Host = null; //实例
        private string _host = string.Empty;
        private int _port = int.MinValue;
        private List<IDataForwarder> _forwaders = null; //转发器集合
        private List<MsgHandlerBase> _msgHandlers = null;//(响应)处理器集合
        private RequestContext _requestContext = null;//请求处理管道
        private CacheService _cacheService = null;

        public JT808GatewayHostBuilder()
        {
            _forwaders = new List<IDataForwarder>();
            _msgHandlers = new List<MsgHandlerBase>();
        }

        /// <summary>
        /// 设置宿主地址
        /// </summary>
        /// <param name="hostIP"></param>
        /// <returns></returns>
        public JT808GatewayHostBuilder SetHost(string hostIP)
        {
            this._host = hostIP;
            return this;
        }

        /// <summary>
        /// 设置宿主端口
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public JT808GatewayHostBuilder SetPort(int port)
        {
            this._port = port;
            return this;
        }

        /// <summary>
        /// 设置转发器
        /// </summary>
        /// <param name="actionSetForwader"></param>
        /// <returns></returns>
        public JT808GatewayHostBuilder SetForwaders(Action<List<IDataForwarder>> forwarders)
        {
            forwarders(_forwaders);
            return this;
        }

        /// <summary>
        /// 设置处理器
        /// </summary>
        /// <param name="collections"></param>
        /// <returns></returns>
        public JT808GatewayHostBuilder SetMeesageHandlers(Action<List<MsgHandlerBase>> handlers)
        {
            handlers(_msgHandlers);
            return this;
        }

        /// <summary>
        /// 服务注入
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public JT808GatewayHostBuilder SetCache(CacheService cache)
        {
            _cacheService = cache;
            return this;
        }

        /// <summary>
        /// 构建
        /// </summary>
        /// <returns></returns>
        public IHost Build()
        {
            MsgHandlerContainer msgHandlerContainer = new MsgHandlerContainer(_msgHandlers);
            _requestContext = new RequestContext(msgHandlerContainer);
            //添加转发器
            _requestContext.Forwarders.AddRange(_forwaders);

            _jT808Host = SuperSocketHostBuilder
                .Create<JT808Package, JT808PackageFilter>()
                .ConfigurePackageHandler(async (session, drPackage) => //设备请求
                {
                    //缓存请求信息
                    _cacheService.StoreCache(drPackage);

                    //记录当前会话请求的包，
                    //以便在会话管理发送消息能查询到会话
                    session.DataContext = drPackage;
                    ((JT808Session)session).SimNumber = drPackage.Header.SimNumber;

                    //处理获得平台响应数据包
                    var dpPackages = _requestContext.Handle(drPackage);
                    foreach (var dpPackage in dpPackages)
                    {
                        //平台响应
                        await session.Channel.SendAsync(dpPackage.WriteMemory(isEsc: true));

                        //缓存最新的流水号
                        _cacheService.StoreSerialNum(dpPackage);
                    }
                })
                .ConfigureSuperSocket(options =>
                {
                    options.Name = "JT808Gateway";
                    options.Listeners = new[] {
                        new ListenOptions{
                            Ip= _host,
                            Port = _port
                        }
                    };
                })
                .UseSession<JT808Session>()
                .Build();
            return _jT808Host;
        }
    }
}